package com.westa.smallshop.util.volley;

import com.alibaba.fastjson.JSON;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import com.android.internal.http.multipart.StringPart;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.westa.smallshop.util.Global.CHARACTER_ENCODING;

public class MultipartRequest<T> extends Request<T> {


    private Class<T> mClazz;
    private Response.Listener<T> mListener;
    private MultipartEntity mMultipartEntity;

    private boolean isHasToken = false;
    private Map<String, String> mHeaders = new HashMap<>();
    private List<Part> mParts = new ArrayList<>();


    public MultipartRequest(String url, Class<T> clazz, Response.Listener<T> listener, Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        mClazz = clazz;
        mListener = listener;
    }

    @Override
    public String getBodyContentType() {
        if (mMultipartEntity == null) {
            mMultipartEntity = new MultipartEntity(mParts.toArray(new Part[mParts.size()]));
        }
        return mMultipartEntity.getContentType().getValue();
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        if (mMultipartEntity == null) {
            mMultipartEntity = new MultipartEntity(mParts.toArray(new Part[mParts.size()]));
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            mMultipartEntity.writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    /*
     * (non-Javadoc)
     *
     * @see com.android.volley.Request#getHeaders()
     */

    public void addParam(String key, String value) {

        if (value != null) {
            mParts.add(new StringPart(key, value, "UTF-8"));
        }
    }

    public void addParams(Map<String, String> params) {

        if (params != null) {

            for (Map.Entry<String, String> entry : params.entrySet()) {
                mParts.add(new StringPart(entry.getKey(), entry.getValue(), "UTF-8"));
            }
        }
    }

    public void addParam(String key, File file) {

        try {
            mParts.add(new FilePart(key, file, "image/png", "UTF-8"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        mHeaders.putAll(MyHttpClient.getHeaders(isHasToken));
        return mHeaders;
    }

    @Override
    protected void deliverResponse(T response) {
        mListener.onResponse(response);
    }

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {

        try {
            String json = new String(response.data, CHARACTER_ENCODING);

            return Response.success(JSON.parseObject(json, mClazz),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (Exception e) {
            return Response.error(new ParseError(e));
        }
    }

    public void setHasToken(boolean hasToken) {
        isHasToken = hasToken;
    }
}
